package com.wlf.server.common.config;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import com.wlf.server.common.service.SysMenuService;
import org.slf4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;
import java.util.List;

/**
 * springMVC配置类
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    private static final Logger log = org.slf4j.LoggerFactory.getLogger(WebMvcConfig.class);
    @Resource
    SysMenuService menuService;
    @Resource
    FileConfig.LocalFileConfig localFileConfig;

    /**
     * 配置本地文件夹映射
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(localFileConfig.getWebPath() + "/**")
                .addResourceLocations("file:" + localFileConfig.getAttachmentPath() + "/");
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }

    // 注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册Sa-Token的路由拦截器
        registry.addInterceptor(new SaInterceptor((o) -> {
            // 这里也是跨域需要写的代码，如果配置了反相代理，建议把这行去掉增加系统接口的安全性。
            SaRouter.match(SaHttpMethod.OPTIONS)
                    .free(r -> log.info("--------OPTIONS预检请求，不做处理"))
                    .stop();
            log.info("-------- 前端访问path：" + SaHolder.getRequest().getRequestPath());
            // 登录认证 -- 拦截所有路由，并排除/main/login 用于开放登录
            SaRouter.match("/**")
                    .notMatch("/actuator/**") // 监控 测试完成后一样需要登录才能访问，不然挺危险
                    .notMatch("/captcha/**") // 验证码
                    .notMatch("/main/login") // 登陆
                    .notMatch("/main/avatar") // 获取头像
                    .notMatch("/main/logout") // 注销登陆
                    .notMatch("/error/**") // 默认错误页面
                    .notMatch(localFileConfig.getWebPath() + "/**") // 附件图片读取
                    .check(r -> StpUtil.checkLogin());
            List<SysMenuService.UrlAndPower> list = menuService.urlAndPowerList();
            for (SysMenuService.UrlAndPower i : list) {
                SaRouter.match(i.getUrl()).check(r -> StpUtil.checkPermission(i.getPower()));
            }
        }));
    }


    /**
     * 解决跨域问题，项目部署的时候可以使用nginx配置一个反向代理，就可以不需要配置这个了。
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .exposedHeaders("Access-Control-Allow-Origin")
                .allowCredentials(true);
        WebMvcConfigurer.super.addCorsMappings(registry);
    }
}

